/**
 * 
 */
package com.wilmar.process.web.interceptors;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionInvocation;
import com.wilmar.process.core.ProcessSystemDeclareKeys;
import com.wilmar.process.core.services.spi.IClassConvertService;
import com.wilmar.process.entity.AbstractBusinessPojo;
import com.wilmar.process.entity.PojoInformation;

/**
 * 业务数据拦截器,将表单数据转换为action可接受的数据结构（pojo）
 * 
 * @author MaKuBEX E-mail:makubexnet@gmail.com
 * @version 1.0.0 at Aug 4, 2009 1:21:27 PM
 * @deprecated
 */
public class BusinessDataInterceptor extends AbstractProcessInterceptor {

	/**
	 * @serialField
	 */
	private static final long serialVersionUID = -6861424461896365230L;

	private IClassConvertService classConvertService;

	/**
	 * @return the classConvertService
	 */
	public IClassConvertService getClassConvertService() {
		return classConvertService;
	}

	/**
	 * @see com.opensymphony.xwork2.interceptor.Interceptor#intercept(com.opensymphony.xwork2.ActionInvocation)
	 */
	public String intercept(ActionInvocation arg0) throws Exception {
		// ProcessActionSupport processActionSupport = (ProcessActionSupport)
		// arg0
		// .getAction();
		HttpServletRequest request = ServletActionContext.getRequest();
		HashMap<String, String[]> paramap = (HashMap<String, String[]>) request
				.getParameterMap();
		HashSet<PojoInformation> pojoInformationSet = new HashSet<PojoInformation>();
		String[] clazz_info = paramap
				.get(ProcessSystemDeclareKeys.PROCESS_SYSTEM_POJOINFORMATION_CLAZZNAME);
		String[] alias_info = paramap
				.get(ProcessSystemDeclareKeys.PROCESS_SYSTEM_POJOINFORMATION_ALIAS);
		if (clazz_info.length != alias_info.length)
			throw new RuntimeException(
					"ClazzNames' count and Aliases' count is not the same");
		for (int index = 0; index < clazz_info.length; index++) {
			PojoInformation pojoInfo = new PojoInformation(clazz_info[index],
					alias_info[index]);
			pojoInformationSet.add(pojoInfo);
		}
		HashSet<List<AbstractBusinessPojo>> businessDataStore = new HashSet<List<AbstractBusinessPojo>>();
		for (PojoInformation pojoInfo : pojoInformationSet) {
			// ��ȡ����
			String alias = pojoInfo.getAlias();
			Iterator<String> paraNameIter = paramap.keySet().iterator();
			// ȷ����ݳ����Լ���Ӧ���
			int dataSize = 0;
			HashMap<String, String[]> needMap = new HashMap<String, String[]>();
			while (paraNameIter.hasNext()) {
				String paraName = paraNameIter.next();
				if (paraName.startsWith(alias + ".")) {
					String[] values = paramap.get(paraName);
					needMap.put(paraName, values);
					if (values.length > dataSize)
						dataSize = values.length;
				}
			}
			if (dataSize > 0) {
				List<AbstractBusinessPojo> list = new ArrayList<AbstractBusinessPojo>(
						dataSize);
				for (int index = 0; index < dataSize; index++) {
					list.add((AbstractBusinessPojo) Class.forName(
							pojoInfo.getClazzName()).newInstance());
				}

				// ����ʽ�������
				for (int index = 0; index < dataSize; index++) {
					paraNameIter = needMap.keySet().iterator();
					Serializable serializablePojo = list.get(index);
					Method[] methods = serializablePojo.getClass().getMethods();
					while (paraNameIter.hasNext()) {
						String paraName = paraNameIter.next();
						String[] values = needMap.get(paraName);
						String tmp = paraName.substring(alias.length() + 1);
						String allowedMethodName = ProcessSystemDeclareKeys.PROCESS_SYSTEM_PROPERTIE_SETTER_PREFIX
								+ tmp.toUpperCase().charAt(0)
								+ tmp.toLowerCase().substring(1);
						for (Method m : methods) {
							if (allowedMethodName.equals(m.getName())) {
								m.invoke(serializablePojo, classConvertService
										.convert(values[index], m
												.getParameterTypes()[0]));
								break;
							}
						}
					}
				}
				if (list.size() > 0)
					businessDataStore.add(list);
			}
		}
		// processActionSupport.setBusinessDataStore(businessDataStore);
		return arg0.invoke();
	}

	/**
	 * @param classConvertService
	 *            the classConvertService to set
	 */
	public void setClassConvertService(IClassConvertService classConvertService) {
		this.classConvertService = classConvertService;
	}

}
